package newprogram;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

// 学生类
class Student {
    String studentId;
    String name;
    List<Course> courses;  // 新增：用于存储课程信息

    Student(String name, String studentId) {  // 构造函数修改，只接收姓名和学号
        this.studentId = studentId;
        this.name = name;
        this.courses = new ArrayList<>();  // 初始化课程列表
    }

    // 添加课程的方法
    public void addCourse(String courseId, String courseName, double totalCredit, double score) {
        courses.add(new Course(courseId, courseName, totalCredit, score));
    }

    // 将百分制成绩转换为等级制成绩
    String convertToLetterGrade(double score) {
        if (90 <= score && score <= 100) {
            return "A";
        } else if (86 <= score && score < 90) {
            return "A-";
        } else if (83 <= score && score < 86) {
            return "B+";
        } else if (80 <= score && score < 83) {
            return "B";
        } else if (76 <= score && score < 80) {
            return "B-";
        } else if (73 <= score && score < 76) {
            return "C+";
        } else if (70 <= score && score < 73) {
            return "C";
        } else if (66 <= score && score < 70) {
            return "C-";
        } else if (63 <= score && score < 66) {
            return "D+";
        } else if (60 <= score && score < 63) {
            return "D";
        } else {
            return "F";
        }
    }

    // 将等级制成绩转换为绩点
    double getGradePoint(String letterGrade) {
        switch (letterGrade) {
            case "A":
                return 4.0;
            case "A-":
                return 3.67;
            case "B+":
                return 3.33;
            case "B":
                return 3.00;
            case "B-":
                return 2.67;
            case "C+":
                return 2.33;
            case "C":
                return 2.00;
            case "C-":
                return 1.67;
            case "D+":
                return 1.33;
            case "D":
                return 1.00;
            default:
                return 0.00;
        }
    }

    public String getStudentId() {
        return studentId;
    }

    public String getName() {
        return name;
    }

    // 计算单个学生的 GPA
    public double calculateGPA() {
        double totalGradePointCredit = 0;
        double totalCredit = 0;
        for (Course course : courses) {
            String letterGrade = convertToLetterGrade(course.getScore());
            double gradePoint = getGradePoint(letterGrade);
            totalGradePointCredit += gradePoint * course.getTotalCredit();
            totalCredit += course.getTotalCredit();
        }
        return totalCredit > 0? totalGradePointCredit / totalCredit : 0;
    }
}

class Course {  // 课程类
    String courseId;
    String courseName;
    double totalCredit;
    double score;

    Course(String courseId, String courseName, double totalCredit, double score) {
        this.courseId = courseId;
        this.courseName = courseName;
        this.totalCredit = totalCredit;
        this.score = score;
    }

    public String getCourseId() {
        return courseId;
    }

    public String getCourseName() {
        return courseName;
    }

    public double getTotalCredit() {
        return totalCredit;
    }

    public double getScore() {
        return score;
    }
}

public class StudentCreditManagementSystem {

    // 从文件读取学生数据
    public static List<Student> readStudentData(String filePath) {
        List<Student> studentList = new ArrayList<>();
        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
            String line;
            while ((line = reader.readLine())!= null) {
                String[] data = line.split(",");
                String name = data[0];
                String studentId = data[1];
                Student student = findOrCreateStudent(studentList, studentId, name);  // 传递姓名
                student.addCourse(data[2], data[3], Double.parseDouble(data[4]), Double.parseDouble(data[5]));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return studentList;
    }

    // 根据学号和姓名查找或创建学生对象
    public static Student findOrCreateStudent(List<Student> studentList, String studentId, String name) {
        for (Student student : studentList) {
            if (student.getStudentId().equals(studentId)) {
                return student;
            }
        }
        Student newStudent = new Student(name, studentId);  // 传递姓名
        studentList.add(newStudent);
        return newStudent;
    }

    // 打印指定学生的综合 GPA
    public static void printStudentTotalGPA(List<Student> students, Scanner scanner) {
        System.out.println("请输入要查询的学生学号：");
        String studentId = scanner.next();
        for (Student student : students) {
            if (studentId.equals(student.getStudentId())) {
                System.out.println(student.getName() + "同学的综合 GPA 为：" + student.calculateGPA());
                return;
            }
        }
        System.out.println("未找到该学号的学生。");
    }

    // 打印指定学生某课程的 GPA 和等级成绩
    public static void printStudentCourseGPA(List<Student> students, Scanner scanner) {
        System.out.println("请输入要查询的学生学号：");
        String studentId = scanner.next();
        System.out.println("请输入查询课程的课程号：");
        String courseId = scanner.next();
        for (Student student : students) {
            if (studentId.equals(student.getStudentId())) {
                for (Course course : student.courses) {
                    if (courseId.equals(course.getCourseId())) {
                        String letterGrade = student.convertToLetterGrade(course.getScore());
                        double gradePoint = student.getGradePoint(letterGrade);
                        System.out.println(student.getStudentId() + "同学的" + courseId + "课程的 GPA 为：" + gradePoint + " 等级成绩为：" + letterGrade);
                        return;
                    }
                }
            }
        }
        System.out.println("未找到该学号学生的该课程成绩。");
    }

    // 按课程名查询
    public static void queryByCourseName(List<Student> students, Scanner scanner) {
        System.out.println("请输入要查询的课程名：");
        String courseName = scanner.next();
        for (Student student : students) {
            for (Course course : student.courses) {
                if (courseName.equals(course.getCourseName())) {
                    String letterGrade = student.convertToLetterGrade(course.getScore());
                    double gradePoint = student.getGradePoint(letterGrade);
                    System.out.println(student.getStudentId() + "同学的" + courseName + "课程的 GPA 为：" + gradePoint + " 等级成绩为：" + letterGrade);
                }
            }
        }
    }

    // 将相同学号学生的综合 GPA 导出到新的 txt 文件
    public static void exportSameStudentIdGPA(List<Student> students) {
        Map<String, Double> studentIdToGPA = new HashMap<>();
        for (Student student : students) {
            if (!studentIdToGPA.containsKey(student.getStudentId())) {
                studentIdToGPA.put(student.getStudentId(), student.calculateGPA());
            }
        }

        try {
            FileWriter f = new FileWriter("C:\\javawork\\IdGPA.txt");
            for (Map.Entry<String, Double> entry : studentIdToGPA.entrySet()) {
                f.write("学号：" + entry.getKey() + "  综合 GPA：" + entry.getValue() + System.lineSeparator());
            }
            f.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 将学生信息写入文件
    public static void writeStudentDataToFile(List<Student> students) {
        try {
            FileWriter f = new FileWriter("C:\\javawork\\students.txt");
            for (Student student : students) {
                for (Course course : student.courses) {
                    f.write("学生姓名：" + student.getName() + "    学生学号：" + student.getStudentId() + System.lineSeparator()
                            + "    课程号：" + course.getCourseId() + "    课程名称：" + course.getCourseName() + "    课程成绩："
                            + course.getScore() + "    课程等级成绩：" + student.convertToLetterGrade(course.getScore()) + "    GPA：" + student.calculateGPA() + System.lineSeparator());
                }
            }
            f.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 按 GPA 降序排序学生
    public static void sortStudentsByGPA(List<Student> students) {
        students.sort(Comparator.comparingDouble(Student::calculateGPA).reversed());
    }

    public static void main(String[] args) {
        // 导入学生信息
        String filePath = "C:\\javawork\\studentData.txt";
        List<Student> students = readStudentData(filePath);

        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.println("请选择操作类型：1.查询某学生综合 GPA；2.查询某学生某课程 GPA；3.按课程名查询本课程所有学生的成绩；4.按 课程GPA 降序排序学生；5.导出学生的综合 GPA；6.退出并导出学生的选课记录及其成绩");
            int choice = scanner.nextInt();

            if (choice == 1) {
                printStudentTotalGPA(students, scanner);
            } else if (choice == 2) {
                printStudentCourseGPA(students, scanner);
            } else if (choice == 3) {
                queryByCourseName(students, scanner);
            } else if (choice == 4) {
                sortStudentsByGPA(students);
                System.out.println("学生已按 课程GPA 降序排序，在退出后可见。");
            } else if (choice == 5) {
                exportSameStudentIdGPA(students);
                System.out.println("学生的综合 GPA 已导出。");
            } else if (choice == 6) {
                break;
            } else {
                System.out.println("无效选择，请重新输入。");
            }
        }

        // 将学生信息写入 txt 文件
        writeStudentDataToFile(students);

        // 关闭 scanner
        scanner.close();
    }
}